#include "device_uart.h"
#include "device_spi.h"

u16 cnt;

u8 state_num;

static u8 g_uart_buf[BUF_SIZE1];
u8 *uart_rx_buffer;

static QueueHandle_t uart1_queue;
static TaskHandle_t uart_task_handle;

void uart_msg_send(u8* buf,u8 length)
{    
    uart_write_bytes(UART_NUM, (const u8 *)buf, length);
}

void print_data_hex(uint8_t *data, u16 len)
{   
    printf("------> data: cache");
    for (int i = 0; i < len; i++) 
    {
        printf(" 0x%x", data[i]);
    }
    
    printf(", len1: %d\n", len);
}


static void UartPortSerialRxPoll(size_t xEventSize)
{
    u16 received;
    cache_param *cache_buffer= NULL;
    u8 *data;
    if (xEventSize > 0) 
    {
        xEventSize>BUF_SIZE1?xEventSize=BUF_SIZE1:0;
        received = uart_read_bytes(UART_NUM, g_uart_buf,xEventSize,portMAX_DELAY);
        //printf("received is %d\n",received);
        cache_buffer = pvPortMalloc(sizeof(cache_param *));
        cache_buffer->len = received;
        data = (u8 *)pvPortMalloc(received*sizeof(u8 *));
        memcpy(data,g_uart_buf,received);
        //print_data_hex(data,received);
        cache_buffer->data=data;

        if (pdPASS != xQueueSend(cache_queue_handle,&cache_buffer,0))
        {
            LOG_INFO("xQueueSend fail\n");
            vPortFree(cache_buffer->data);
            vPortFree(cache_buffer);
        }

    } else 
    {
        LOG_INFO("size is zero, ignore...\n");
    }
}


static void uart_event_task(void *pvParameters)
{
    uart_event_t event;
    for (;;) 
    {
        if (xQueueReceive(uart1_queue, (void *)&event, (TickType_t)portMAX_DELAY)) 
        {
            switch (event.type) 
            {
                case UART_DATA:
                    UartPortSerialRxPoll(event.size);
                    break;
                //Event of HW FIFO overflow detected
                case UART_FIFO_OVF:
                    LOG_INFO("hw fifo overflow\n");
                    uart_flush_input(UART_NUM);
                    xQueueReset(uart1_queue);
                    break;
                //Event of UART ring buffer full
                case UART_BUFFER_FULL:
                    LOG_INFO("ring buffer full");
                    uart_flush_input(UART_NUM);
                    xQueueReset(uart1_queue);
                    break;
                //Event of UART RX break detected
                case UART_BREAK:
                    LOG_INFO("uart rx break");
                    uart_flush_input(UART_NUM);
                    xQueueReset(uart1_queue);
                    break;
                //Event of UART parity check error
                case UART_PARITY_ERR:
                    LOG_INFO("uart parity error");
                    break;
                //Event of UART frame error
                case UART_FRAME_ERR:
                    LOG_INFO("uart frame error");
                    break;
                //Others
                default:
                    LOG_INFO("uart event type: %d\n", event.type);
                    break;
            }
        }
    }
    vTaskDelete(NULL);
}

void uart_config(uint32_t baud_rate, bool use_ref_tick)
{
    uart_config_t uart_config = {
        .baud_rate = baud_rate,
        .data_bits = UART_DATA_8_BITS,
        .parity = UART_PARITY_DISABLE,
        .stop_bits = UART_STOP_BITS_1,
        .flow_ctrl = UART_HW_FLOWCTRL_DISABLE,
        .source_clk = UART_SCLK_DEFAULT,
    };

    uart_param_config(UART_NUM, &uart_config); //串口配置
    uart_set_pin(UART_NUM, UART1_TX_PIN, UART1_RX_PIN, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE); //串口初始化
    uart_driver_install(UART_NUM, BUF_SIZE1*2, BUF_SIZE1*2, 10, &uart1_queue, ESP_INTR_FLAG_LOWMED); //低优先级的中断
}

void device_uart_init(void) //串口任务初始化
{
    printf("device_uart_int():enter");
    uart_config(UART_RATE, false);
    xTaskCreate(uart_event_task, "uart_queue_task", 4096, NULL, TASK_PROP_NETWORK, &uart_task_handle);
}


